export = {}
//第三方的 其他人写的一些扩展方法

//求差集
let person1 = {
  name: 'ahhh',
  age: 123,
  address: '熊猫基地'
}

let person2 = {
  address: '熊猫基地',
  a: 'ff'
}

type Diff<T extends object,K extends object> = Omit<T, keyof K>
type returnType = Diff<typeof person2,typeof person1>
/*
type returnType = {
  a: string;
}
*/


//求交集
type InterSection<T extends object,K extends object> = Pick<T,Extract<keyof T, keyof K>>
type returnType2 = InterSection<typeof person1,typeof person2>


// Overwrite 覆盖属性
// 下面例子中 Person2代表新, Person1代表旧
// 如果存在了属性 用新的覆盖掉
// 如果老的没有 新的有 不会追加
// 如果老的有 新的没有 会删除
// todo emmm 那么问题来了 这和直接使用新的类型 有撒区别
//      --->如果老的没有 新的有 不会追加
interface Person1 {
  name: string;
  age: number;
  a: number;
}
interface Person2{
  // name: string;
  age: string;
  address: string;
}
type Overwrite<T extends object,K extends object> = Omit<T,keyof Diff<T, K>> & Pick<K,keyof Diff<K, T>>
type returnType3 = Overwrite<Person2,Person1>
let myType:returnType3 = {
  a: 1,
  name: 'string',
  age: 'string'
}


// merge对象合并
let t1 = {name: 'ahhh',a:1}
let t2 = {age:11,a:'string'}
type T3 = typeof t1 & typeof t2
/*
type t3 = {
  name: string;
  a: number;
} & {
  age: number;
  a: string;
}
*/
//↑ 上面的结果并不是我们期望的 ↓会报错
let t3:T3 = {
  name:'ahhh',
  a:'123',
  age:123
}


type T4 = Merge<typeof t1, typeof t2>
let t4:T4 = {
  name:'ahhh',
  a:'123',
  age:123
}

// type Merge<T,K> = Omit<T, keyof K> & K
// 虽然现在已经实现了功能, 但类型展示并不友好
// 鼠标移动到T4上:
/*
let t4: Merge<{
  name: string;
  a: number;
}, {
  age: number;
  a: string;
}>
*/

type Compute<T> = {[K in keyof T]:T[K]}
type Merge<T,K> = Compute<Omit<T, keyof K> & K>
// 鼠标移动到T4上, 现在类型已经友好的展示
/*
type T4 = {
  name: string;
  age: number;
  a: string;
}
*/




//有一个组件, 它接口 age、name、company三个属性都是可选的, 但是如果传入了name, 那就必须要传入
interface Test1 {
  age?: number;
  name?: string;
  company?: string;
}
interface Test2 {
  age: number;
  name: string;
  company?: string;
}
type NewType<T> = T extends { name: string } ? Test2 : Test1;
function getFn<T>(v: NewType<T>){

}
let person = {name:'ahhh',age:123}
getFn<typeof person>(person)
